import Vue from "vue"
import { TYPE_ADD, TYPE_EDIT, TYPE_PREVIEW, TYPE_DEL, TYPE_LIST } from "./token"

export async function _request({ url, method = 'GET', data, params }) {
  try {
    let reqUrl = url
    if(params) reqUrl = reqUrl + '?' + new URLSearchParams(Object.entries(params))
    const response = await fetch( reqUrl, {
      method,
      body: data
    })
    return response.json()
  } catch (e) {
    return Promise.reject(e)
  }
}

export function combineUrl(baseUrl = '', path = '') {
  if(baseUrl.includes('?')) return baseUrl
  if(baseUrl.endsWith('/')) return baseUrl + path
  return baseUrl + '/' + path
}

export function type(o) {
  return Object.prototype.toString.call(o).slice(8, -1).toLowerCase()
}

export function isEmptyObj(o) {
  return Object.keys(o).length === 0 && Object.getOwnPropertySymbols(o).length === 0
}

export function checkCompUsePosition(flag, compName, rightPosition) {
  if(flag) {
    console.error(`${compName} 只能在[${rightPosition}]中使用`);
  }
}

export function checkUnSetUrlError(type, url) {
  if(type === TYPE_PREVIEW) return
  if(!url) {
    let comp
    switch (type) {
      case TYPE_LIST:
        comp = 'crud-table-v2'
        break;
      case TYPE_EDIT:
        comp = 'crud-table-btn-edit'
        break
      case TYPE_ADD:
        comp = 'crud-table-btn-add'
        break
      case TYPE_DEL:
        comp = 'crud-table-btn-del'
        break
      default:
        comp = type
        break;
    }
    console.error(`请设置 [${comp}] 组件的 url 接口地址`);
  }
  return !!url
}

export function formatData(raw, formatter, delOldPro = false) {
  const newData = { ...raw }
  // for(const k in newData) {
  //   if(newData[k] === undefined || newData[k] === '')
  //     delete newData[k]
  // }
  if (!formatter) return newData
  if (type(formatter) === 'object') {
    for (const prop in formatter) {
      if (newData[prop]) {
        Object.assign(newData, formatter[prop](newData[prop]))
        if (delOldPro) delete newData[prop]
      }
    }
  }
  if (type(formatter) === 'function') {
    formatter(newData)
  }
  return newData
}

/**
 * 合成v-model
 * @param nodes 节点
 * @param obj 响应式对象
 * @returns {null|*}
 */
 export function mergeVModel(nodes, obj, isReadonly = false) {
  if (!nodes) return null
  return nodes.map(v => {
    if (!v.componentOptions) {
      v.children = mergeVModel.call(this, v.children, obj)
    } else if (v.componentOptions.tag !== 'el-form-item' && v.componentOptions.children) {
      v.componentOptions.children = mergeVModel.call(this, v.componentOptions.children, obj)
    } else {
      if (v.data.attrs.skip !== undefined) return v
      const modelKey = v.componentOptions.propsData.prop
      if (modelKey === undefined) throw '必须在el-form-item 指定 prop'
      v.componentOptions.children.map(el => {
        // fix: Cannot destructure property 'propsData' of 'a.componentOptions' as it is undefined.
        if (!el || !el?.componentOptions) return null
        const { propsData } = el.componentOptions
        if (propsData === undefined) {
          el.componentOptions.propsData = {}
        } else {
          const defaultValue = propsData.value
          if (defaultValue && !obj[modelKey]) {
            obj[modelKey] = defaultValue
          }
        }
        if(isReadonly) el.componentOptions.propsData.readonly = true
        el.componentOptions.propsData.value = obj[modelKey]
        if (el.componentOptions.listeners === undefined) {
          el.componentOptions.listeners = {}
        }
        el.componentOptions.listeners.input = e => {
          Vue.set(obj, modelKey, e)
        }
        el.componentOptions.listeners.clear = e => {
          Vue.set(obj, modelKey, undefined)
        }
        return el
      })
    }
    return v
  })
}

const root = Vue.prototype
/**
 * 提示框
 * @param type
 * @param title 提示标题
 * @param successTip 操作成功后提示的文字
 * @param loadingText
 * @param reqEntity 请求体
 * @returns {Promise<void>}
 */
 export function func_ask_for({ type = 'warning', title = '此操作将删除该记录, 是否继续?', loadingText = '正在删除', successTip = '删除成功', ...reqEntity }) {
  return new Promise(resolve => {
    root
      .$confirm(title, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type,
        beforeClose: async (action, instance, done) => {
          if (action === 'cancel') {
            done()
          } else {
            try {
              instance.confirmButtonLoading = true
              instance.confirmButtonText = loadingText
              const res = await this.$_request(reqEntity)
              root.$message.success(res.msg || res.message || successTip)
              done()
            } catch (e) {
              instance.confirmButtonText = '重试'
              console.log(e)
            } finally {
              instance.confirmButtonLoading = false
            }
          }
        }
      })
      .then(resolve)
      .catch(e => e)
  })
}